package com.boyuan.system.utils;

import com.boyuan.system.callback.ThermInfoCallback;
import com.boyuan.system.enums.HCPlayControlEnum;
import com.boyuan.system.hik.HCNetSDK;
import com.boyuan.system.model.vo.LoginVo;
import com.boyuan.system.model.vo.LogoutIdRequestVo;
import com.boyuan.system.websocket.BlockQueue;
import com.boyuan.system.websocket.WebsocketServer;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.websocket.Session;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import static com.boyuan.system.hik.HCNetSDK.NET_DVR_GET_REALTIME_THERMOMETRY;
import static com.boyuan.system.hik.HCNetSDK.NET_DVR_GET_THERMOMETRYRULE_TEMPERATURE_INFO;

/**
 * 摄像头预览工具类
 *
 * @author ply
 * @date 2023-11-20
 */
@Slf4j
public class PreviewUtil {
    //是否初始化
    public static boolean isInit = false;
    //海康SDK接口
    public static HCNetSDK hcNetSDK = null;
    //异常捕获回调
    public static PreviewUtil.FexceptionCallBack fexceptionCallBack;
    private static IntByReference m_err;//错误号
    private static HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo;//设备信息
    private static HCNetSDK.NET_DVR_IPPARACFG m_strIpparaCfg;//IP参数

    /**
     * 异常信息捕获接收类
     */
    protected static class FexceptionCallBack implements HCNetSDK.FExceptionCallBack {

        @Override
        public void invoke(int dwType, int lUserID, int lHandle, Pointer pUser) {
            switch (dwType) {
                case HCNetSDK.EXCEPTION_AUDIOEXCHANGE:
                    log.info("登录id：" + lUserID + "语音对讲时网络异常");
                    break;
                case HCNetSDK.EXCEPTION_ALARM:
                    log.info("登录id：" + lUserID + "报警上传时网络异常");
                    break;
                case HCNetSDK.EXCEPTION_PLAYBACK:
                    log.info("登录id：" + lUserID + "网络预览时异常");
                    break;
                case HCNetSDK.EXCEPTION_SERIAL:
                    log.info("登录id：" + lUserID + "透明通道传输时异常");
                    break;
                case HCNetSDK.EXCEPTION_RECONNECT:
                    log.info("登录id" + lUserID + "预览时重连");
                    break;
                default:
                    log.info("登录id:" + lUserID + ",异常事件类型:" + Integer.toHexString(dwType));
                    log.info("具体错误参照 SDK网络使用手册中：NET_DVR_SetExceptionCallBack_V30 方法中的异常定义！");
                    break;
            }
        }
    }

    /**
     * 加载海康威视动态库
     */
    private static boolean CreateSDKInstance() {
        if (hcNetSDK == null) {
            synchronized (HCNetSDK.class) {
                String strDllPath = "";
                try {
                    if (OsSelect.isWindows())
                        //win系统加载库路径
                        strDllPath = System.getProperty("user.dir") + "\\lib\\win\\HCNetSDK.dll";
                    else if (OsSelect.isLinux())
                        //Linux系统加载库路径
                        strDllPath = System.getProperty("user.dir") + "/lib/linux/libhcnetsdk.so";

                    log.info("loadLibrary: " + strDllPath);
                    hcNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
                } catch (Exception ex) {
                    log.info("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 加载海康威视播放库
     */
    private static boolean CreatePlayInstance() {
        if (hcNetSDK == null) {
            synchronized (HCNetSDK.class) {
                String strPlayPath = "";
                try {
                    if (OsSelect.isWindows())
                        //win系统加载库路径
                        strPlayPath = System.getProperty("user.dir") + "\\lib\\win\\PlayCtrl.dll";
                    else if (OsSelect.isLinux())
                        //Linux系统加载库路径
                        strPlayPath = System.getProperty("user.dir") + "/lib/linux/libPlayCtrl.so";
                    hcNetSDK = (HCNetSDK) Native.loadLibrary(strPlayPath, HCNetSDK.class);

                } catch (Exception ex) {
                    log.info("loadLibrary: " + strPlayPath + " Error: " + ex.getMessage());
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 类初始化时加载海康威视SDK
     * <p>
     * *@PostConstruct 便于直接加载注入类
     */
    @PostConstruct
    public static void init() {
        m_err = new IntByReference(-1);
        log.info("加载海康威视SDK dll");
        log.info("初始化路径为：" + System.getProperty("user.dir") + "\\lib\\win\\HCNetSDK.dll");
        if (hcNetSDK == null) {
            if (!CreateSDKInstance()) {
                log.info("Load SDK fail");
                return;
            }
            if (!CreatePlayInstance()) {
                log.info("Load PlayCtrl fail");
                return;
            }
        }
        log.info("海康威视SDK dll加载成功");
        //linux系统建议调用以下接口加载组件库
        if (OsSelect.isLinux()) {
            HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
            HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
            //这里是库的绝对路径，请根据实际情况修改，注意改路径必须有访问权限
            String strPath1 = System.getProperty("user.dir") + "/lib/linux/libcrypto.so.1.1";
            String strPath2 = System.getProperty("user.dir") + "/lib/linux/libssl.so.1.1";
            System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
            ptrByteArray1.write();
            hcNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());
            System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
            ptrByteArray2.write();
            hcNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());
            String strPathCom = System.getProperty("user.dir") + "/lib";
            HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
            System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
            struComPath.write();
            hcNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
        }

        log.info("开始初始化海康威视Sdk");
        //SDK初始化，一个程序只需要调用一次
        boolean initSuc = hcNetSDK.NET_DVR_Init();
        if (!initSuc) {
            log.info("初始化海康威视Sdk失败");
        }
        log.info("海康威视Sdk初始化成功！");
        log.info("开始设置异常消息回调");
        //异常消息回调
        if (fexceptionCallBack == null) {
            fexceptionCallBack = new PreviewUtil.FexceptionCallBack();
        }
        Pointer pUser = null;
        if (!hcNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fexceptionCallBack, pUser)) {
            return;
        }
        log.info("设置异常消息回调成功");
        log.info("开始设置启动SDK写日志");
        //启动SDK写日志
        hcNetSDK.NET_DVR_SetLogToFile(3,  System.getProperty("user.dir") + "\\sdkLog\\", false);
        isInit = true;
    }

    /**
     * 类销毁时清理sdk
     */
    @PreDestroy
    public void clearSdk() {
        if (null != hcNetSDK) {
            //SDK反初始化，释放资源，只需要退出时调用一次
            hcNetSDK.NET_DVR_Cleanup();
        }
    }

    /*=============================业务方法=============================*/

    /**
     * 摄像头登陆(支持多个)
     *
     * @param loginVoList 登录信息
     */
    public static List<LoginVo> loginCamera(List<LoginVo> loginVoList) {
        if (loginVoList.size() != 0) {
            for (LoginVo loginVo : loginVoList) {
                //判断初始化海康威视摄像头
                if (!isInit) {
                    init();
                }
                //如果已经登录，就先退出登录
                /*String userId = BlockQueue.findUserIdByIp(loginVo.getIp());
                if (userId != null) {
                    logoutPlayView(userId);
                }*/
                //登录设备，每一台设备分别登录，登录句柄是唯一，可以区分设备
                //设备登录信息
                HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
                //设备信息
                HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
                //设备ip地址
                loginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
                System.arraycopy(loginVo.getIp().getBytes(), 0, loginInfo.sDeviceAddress, 0, loginVo.getIp().length());
                //设备用户名
                loginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
                System.arraycopy(loginVo.getUsername().getBytes(), 0, loginInfo.sUserName, 0, loginVo.getUsername().length());
                //设备密码
                loginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
                System.arraycopy(loginVo.getPassword().getBytes(), 0, loginInfo.sPassword, 0, loginVo.getPassword().length());
                //SDK端口
                loginInfo.wPort = Short.parseShort(loginVo.getPort());
                //是否异步登录
                loginInfo.bUseAsynLogin = false;
                loginInfo.write();
                log.info("设备：" + loginVo + "发送登录请求！");
                //发送设备登录请求
                int loginUserId = hcNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo);
                m_strDeviceInfo = deviceInfo;//获取设备参数结构
                //short iPort = Integer.valueOf(loginVo.getPort()).shortValue();
                //int loginUserId = hcNetSDK.NET_DVR_Login_V30(loginVo.getIp(), iPort, loginVo.getUsername(), loginVo.getPassword(), m_strDeviceInfo);//登录设备
                if (loginUserId == -1) {
                    log.info("设备信息：" + loginVo + "登录失败，错误码：" + hcNetSDK.NET_DVR_GetLastError());
                    log.info(hcNetSDK.NET_DVR_GetErrorMsg(m_err));
                    loginVo.setLoginStatus("0");
                    loginVo.setLoginMessage("登录失败，错误码：" + hcNetSDK.NET_DVR_GetLastError());
                    loginVo.setUserId(null);
                } else {
                    log.info("设备信息：" + loginVo + "登录成功！设备序列号：" + new String(deviceInfo.struDeviceV30.sSerialNumber));
                    loginVo.setLoginStatus("1");
                    loginVo.setLoginMessage("登录成功！设备序列号：" + new String(deviceInfo.struDeviceV30.sSerialNumber));
                    loginVo.setUserId(loginUserId);
                    deviceInfo.read();
                    //记录ip已经登录
                    BlockQueue.ipToUserIdMap.put(loginVo.getIp(), loginVo.getUserId().toString());
                    loginVo.setChannelList(getChannel(loginVo));
                }
            }
        }
        return loginVoList;
    }

    /**
     * 实时预览一个摄像头
     *
     * @param loginVo 登录信息
     * @return 摄像头信息
     */
    public static LoginVo playViewCamera(LoginVo loginVo) {
        if (StringUtils.isEmpty(loginVo.getChannelId())) {
            //设备信息
            HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
            loginVo.setChannelId((int) deviceInfo.struDeviceV30.byStartDChan);
        }
        VideoPreview.realPlay(loginVo.getUserId(), loginVo.getChannelId());
        if (VideoPreview.lPlayStatus) {
            loginVo.setPlayStatus("1");
            loginVo.setPlayMessage("发送预览请求成功！");
            loginVo.setPlayId(VideoPreview.lPlay);
            log.info("预览请求成功：" + loginVo);
            //创建数据体，等待视频流实时回调
            BlockingQueue blockingQueue = new ArrayBlockingQueue<>(10);
            BlockQueue.bqMap.put(loginVo.getUserId().toString(), blockingQueue);
            BlockQueue.playToUserIdMap.put(loginVo.getPlayId().toString(), loginVo.getUserId().toString());
        } else {
            loginVo.setPlayStatus("0");
            loginVo.setPlayMessage("预览失败：" + VideoPreview.lPlayErrorMassage);
            loginVo.setPlayId(null);
        }
        return loginVo;
    }

    /**
     * 登录并播放摄像头视频
     *
     * @param loginVo 登录参数
     * @return 登录结果
     */
    public static LoginVo loginAndPlayView(LoginVo loginVo) {
        if (!isInit) {
            init();
        }
        //如果已经登录，就先退出登录
       /* String userId = BlockQueue.findUserIdByIp(loginVo.getIp());
        if (userId != null) {
            logoutPlayView(userId);
        }*/
        //设备登录
        List<LoginVo> loginVoList = new ArrayList<>();
        loginVoList.add(loginVo);
        loginCamera(loginVoList);
        if ("1".equals(loginVo.getLoginStatus())) {
            if ("1".equals(loginVoList.get(0).getLoginStatus())) {
                playViewCamera(loginVoList.get(0));
            } else {
                log.info("设备信息：" + loginVo + "登录成功，预览失败！");
                //登录并预览接口中，如果登录成功但是预览失败，自动退出登录-清理数据体
                logoutPlayView(loginVo.getUserId().toString());
            }
        } else {
            log.info("设备信息：" + loginVo + "登录失败！");
        }
        return loginVoList.get(0);
    }

    /**
     * 摄像头退出登录
     *
     * @param userId 登录id
     * @param playId 预览id
     */
    public static void logoutPlayView(String userId, String playId) {
        if (hcNetSDK != null && BlockQueue.bqMap.containsKey(userId)) {
            if (hcNetSDK.NET_DVR_StopRealPlay(Integer.parseInt(playId))) {
                log.info("playId:" + playId + " 停止预览成功");
            }
            //退出程序时调用，每一台设备分别注销
            if (hcNetSDK.NET_DVR_Logout(Integer.parseInt(userId))) {
                log.info("userId:" + userId + " 注销登录成功");
            }
            //清理数据体
            BlockQueue.clearUserId(userId, true);
            WebsocketServer websocketServer = new WebsocketServer();
            Session session = BlockQueue.findSessionByUserId(userId);
            if (session != null) {
                websocketServer.onClose(session);
            }
            log.info("当前已经登录设备：" + BlockQueue.bqMap.keySet());
        }
    }

    /**
     * 摄像头退出登录(自动判断是否在预览并停止)
     *
     * @param userId 登录id
     */
    public static void logoutPlayView(String userId) {
        if (hcNetSDK != null && BlockQueue.bqMap.containsKey(userId)) {
            String playId = BlockQueue.findPlayIdByUserId(userId);
            if (hcNetSDK.NET_DVR_StopRealPlay(Integer.parseInt(playId))) {
                log.info("playId:" + playId + " 停止预览成功");
            }
            //退出程序时调用，每一台设备分别注销
            if (hcNetSDK.NET_DVR_Logout(Integer.parseInt(userId))) {
                log.info("userId:" + userId + " 注销登录成功");
            }
            //清理数据体
            BlockQueue.clearUserId(userId, true);
            WebsocketServer websocketServer = new WebsocketServer();
            Session session = BlockQueue.findSessionByUserId(userId);
            if (session != null) {
                websocketServer.onClose(session);
            }
            log.info("当前已经登录设备：" + BlockQueue.bqMap.keySet());
        }
    }

    /**
     * 只关闭某个摄像头预览，但不退出登录
     *
     * @param loginVo 登录参数
     */
    public static LoginVo logoutPlayViewOnly(LoginVo loginVo) {
        if (hcNetSDK != null) {
            if (loginVo.getPlayId() != null) {
                if (hcNetSDK.NET_DVR_StopRealPlay(loginVo.getPlayId())) {
                    log.info("playId:" + loginVo.getPlayId() + " 停止预览成功");
                    loginVo.setPlayId(null);
                    loginVo.setPlayMessage("停止预览成功");
                    loginVo.setLoginStatus("0");
                } else {
                    //接口返回失败请调用NET_DVR_GetLastError获取错误码，通过错误码判断出错原因。
                    loginVo.setPlayMessage("停止预览失败：接口返回失败请调用NET_DVR_GetLastError获取错误码，通过错误码判断出错原因。");
                }
            }
            //清理数据体
            BlockQueue.clearUserId(loginVo.getUserId().toString(), false);
        }
        return loginVo;
    }

    public static boolean playControl(LoginVo loginVo, Integer mill, String command) throws InterruptedException {
        if (!isInit) {
            init();
        }
        //如果未登录，就先登录
        String userId = BlockQueue.findUserIdByIp(loginVo.getIp());
        List<LoginVo> loginVoList = new ArrayList<>();
        if (userId == null || userId.equals("")) {
            loginVoList.add(loginVo);
            //设备登录
            loginCamera(loginVoList);
        }
        HCPlayControlEnum controlEnum = HCPlayControlEnum.valueOf(command);
        boolean playHandle = false;
        //开始控制
        playHandle = hcNetSDK.NET_DVR_PTZControl_Other(userId.length() > 0 ? Integer.parseInt(userId) : loginVoList.get(0).getUserId(),1,controlEnum.getCode(),0);
        if(!playHandle){
            String err = hcNetSDK.NET_DVR_GetErrorMsg(m_err);
            log.warn("(开始)控制失败!错误原因:" + m_err.getValue() + "," + err);
            return false;
        }
        //控制时间
        Thread.sleep(mill);
        //停止控制
        playHandle = hcNetSDK.NET_DVR_PTZControl_Other(userId.length() > 0 ? Integer.parseInt(userId) : loginVoList.get(0).getUserId(),1,controlEnum.getCode(),1);
        if(!playHandle){
            String err = hcNetSDK.NET_DVR_GetErrorMsg(m_err);
            log.warn("(停止)控制失败!错误原因:" + m_err.getValue() + "," + err);
            return false;
        }
        return true;
    }

    public static List<String> getChannel(LoginVo loginVo) {
        if (!isInit) {
            init();
        }
        //如果未登录，就先登录
        String userId = BlockQueue.findUserIdByIp(loginVo.getIp());
        List<LoginVo> loginVoList = new ArrayList<>();
        if (userId == null || userId.equals("")) {
            loginVoList.add(loginVo);
            //设备登录
            loginCamera(loginVoList);
        }

        List<String> channelList = new ArrayList<>();

        IntByReference ibrBytesReturned = new IntByReference(0);//获取IP接入配置参数
        boolean bRet = false;
        m_strIpparaCfg = new HCNetSDK.NET_DVR_IPPARACFG();
        m_strIpparaCfg.write();
        Pointer lpIpParaConfig = m_strIpparaCfg.getPointer();
        bRet = (m_strDeviceInfo.struDeviceV30.byIPChanNum != 0);

        String devices = "";
        if (!bRet) {
            //设备不支持,则表示没有IP通道
            for (int iChannum = 0; iChannum < m_strDeviceInfo.struDeviceV30.byChanNum; iChannum++) {
                devices = "Camera" + (iChannum + m_strDeviceInfo.struDeviceV30.byStartChan);
                channelList.add(devices);
            }
        } else {
            //设备支持IP通道
            boolean ok = hcNetSDK.NET_DVR_GetDVRConfig(userId.length() > 0 ? Integer.parseInt(userId) : loginVoList.get(0).getUserId(), HCNetSDK.NET_DVR_GET_IPPARACFG, 0, lpIpParaConfig, m_strIpparaCfg.size(), ibrBytesReturned);
            if (!ok) {
                String err = hcNetSDK.NET_DVR_GetErrorMsg(m_err);
                log.info("获取配置失败：" + m_err.getValue() + "," + err);
            }
            m_strIpparaCfg.read();

            for (int iChannum = 0; iChannum < m_strDeviceInfo.struDeviceV30.byChanNum; iChannum++) {
                if(m_strIpparaCfg.byAnalogChanEnable[iChannum] == 1)
                {
                    devices = "Camera" + (iChannum + m_strDeviceInfo.struDeviceV30.byStartChan);
                    channelList.add(devices);
                }
            }

            for (int iChannum = 0; iChannum < HCNetSDK.MAX_IP_CHANNEL; iChannum++) {
                if (m_strIpparaCfg.struIPChanInfo[iChannum].byEnable == 1) {
                    devices = "IP" + (hcNetSDK.NET_DVR_SDKChannelToISAPI(userId.length() > 0 ? Integer.parseInt(userId) : loginVoList.get(0).getUserId(),iChannum + m_strDeviceInfo.struDeviceV30.byStartDChan,true));
                    String channelIP = (new String(m_strIpparaCfg.struIPDevInfo[iChannum].struIP.sIpV4));
                    channelIP = channelIP.trim();
                    devices = devices + "," + channelIP;
                    channelList.add(devices);
                }
            }
        }
        return channelList;
    }

    public static Map<String,Float> getTemperature(LoginVo loginVo) throws InterruptedException {
        if (!isInit) {
            init();
        }
        ThermInfoCallback thermInfoCallback = new ThermInfoCallback();
        //如果未登录，就先登录
        String userId = BlockQueue.findUserIdByIp(loginVo.getIp());
        List<LoginVo> loginVoList = new ArrayList<>();
        if (userId == null || userId.equals("")) {
            loginVoList.add(loginVo);
            //设备登录
            loginCamera(loginVoList);
        }
        HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND thermometry = new HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND();
        thermometry.dwSize = thermometry.size();
        thermometry.byRuleID = 0;
        thermometry.dwChan = 2;
        thermometry.write();
        Pointer pUserData = new Memory(37);
        pUserData.setString(0, loginVo.getIp());
        pUserData.setInt(13,222);

        /*HCNetSDK.NET_DVR_THERMOMETRYRULE_TEMPERATURE_INFO thermometryrule = new HCNetSDK.NET_DVR_THERMOMETRYRULE_TEMPERATURE_INFO();
        thermometryrule.read();*/

        int lHandle = hcNetSDK.NET_DVR_StartRemoteConfig(userId.length() > 0 ? Integer.parseInt(userId) : loginVoList.get(0).getUserId(), NET_DVR_GET_REALTIME_THERMOMETRY, thermometry.getPointer(), thermometry.size(), thermInfoCallback, pUserData);
        /*boolean getDVRConfig = hcNetSDK.NET_DVR_GetDVRConfig(userId.length() > 0 ? Integer.parseInt(userId) : loginVoList.get(0).getUserId(), NET_DVR_GET_THERMOMETRYRULE_TEMPERATURE_INFO, 2, thermometryrule.getPointer(), thermometryrule.size(), new IntByReference(64));
        System.out.println(getDVRConfig);
        if (!getDVRConfig) {
            log.error(loginVo.getIp()+"NET_DVR_GetDVRConfig failed, error code: "+ hcNetSDK.NET_DVR_GetLastError());
        }*/
        if (lHandle < 0){
            log.error(loginVo.getIp()+"NET_DVR_GET_REALTIME_THERMOMETRY failed, error code: "+ hcNetSDK.NET_DVR_GetLastError());
            //break;
        }else{
            log.info(loginVo.getIp()+"NET_DVR_GET_REALTIME_THERMOMETRY is successful!");
        }
        /*while (true){
            int lHandle = hcNetSDK.NET_DVR_StartRemoteConfig(userId.length() > 0 ? Integer.parseInt(userId) : loginVoList.get(0).getUserId(), NET_DVR_GET_REALTIME_THERMOMETRY, thermometry.getPointer(), thermometry.size(), thermInfoCallback, pUserData);

            if (lHandle < 0){
                log.error(loginVo.getIp()+"NET_DVR_GET_REALTIME_THERMOMETRY failed, error code: "+ hcNetSDK.NET_DVR_GetLastError());
                break;
            }else{
                log.info(loginVo.getIp()+"NET_DVR_GET_REALTIME_THERMOMETRY is successful!");
            }
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }*/
        Thread.sleep(1000);
        hcNetSDK.NET_DVR_StopRemoteConfig(lHandle);
        Map<String,Float> temperatureMap = BlockQueue.findTemperatureByIp(loginVo.getIp());
        return temperatureMap;
    }

    public static void logoutPlayViewAll(List<LogoutIdRequestVo> logoutIdRequestVoList) {
        logoutIdRequestVoList.forEach(logoutIdRequestVo -> {
            if (hcNetSDK != null && BlockQueue.bqMap.containsKey(logoutIdRequestVo.getUserId())) {
                if (hcNetSDK.NET_DVR_StopRealPlay(Integer.parseInt(logoutIdRequestVo.getPlayId()))) {
                    log.info("playId:" + logoutIdRequestVo.getPlayId() + " 停止预览成功");
                }
                //退出程序时调用，每一台设备分别注销
                if (hcNetSDK.NET_DVR_Logout(Integer.parseInt(logoutIdRequestVo.getUserId()))) {
                    log.info("userId:" + logoutIdRequestVo.getUserId() +  " 注销登录成功");
                }
                //清理数据体
                BlockQueue.clearUserId(logoutIdRequestVo.getUserId(), true);
                WebsocketServer websocketServer = new WebsocketServer();
                Session session = BlockQueue.findSessionByUserId(logoutIdRequestVo.getUserId());
                if (session != null) {
                    websocketServer.onClose(session);
                }
                log.info("当前已经登录设备：" + BlockQueue.bqMap.keySet());
            }
        });
    }

}
